package org.sparkle.web.filter;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sparkle.cache.AppSession;
import org.sparkle.db.basic.ServiceManager;
import org.sparkle.db.company.CompanyVO;
import org.sparkle.html.api.AppState;
import org.sparkle.web.session.MainManager;

public class RouteFilter implements Filter {

	private ConcurrentMap<String, CompanyVO> companies;
	private Logger log=LoggerFactory.getLogger(RouteFilter.class);
	
	private String staticRegExp;
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
				
		HttpServletRequest request=(HttpServletRequest)arg0;
		
		if(request.getRequestURI().matches(staticRegExp)){
			arg2.doFilter(arg0, arg1);
			return;
		}
		
		HttpServletResponse response=(HttpServletResponse)arg1;
		HttpSession session=request.getSession();
		
		AppSession appSession=(AppSession) session.getAttribute("APPLICATION");
		
		if(appSession==null){
			appSession=new AppSession();
			appSession.setId(session.getId());
		}
		
		appSession.setAppState(new AppState());
		
		MainManager.setAppSession(appSession);
		
		ServiceManager serviceManager=(ServiceManager) session.getAttribute("SERVICE_MANAGER");
		
		MainManager.setServiceManager(serviceManager);
		
		String clientHost = request.getHeader("host");
		
		if(clientHost!=null){
			log.debug("Client HOSTNAME: "+clientHost);
			boolean match=false;
			for(String s: getCompanies().keySet()){
				if(clientHost.matches(s)){
					log.debug("Client HOSTNAME MATCH: "+s);										
					getCompanies().get(s).getApplication().route(request,response,appSession);
					match=true;
					break;
				}
			}
			
			//No matches, return default
			if(!match)
				getCompanies().get("localhost(:[0-9]*)").getApplication().route(request,response,appSession);
		}
		
		MainManager.clean();
		session.setAttribute("APPLICATION",appSession);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		List<CompanyVO> compList= new ServiceManager().getCompanyService().all();
		for(CompanyVO comp: compList){
			getCompanies().put(comp.getHostname(), comp);
		}
		
		staticRegExp=arg0.getInitParameter("staticRegExp");
	}

	public ConcurrentMap<String, CompanyVO> getCompanies() {
		if(companies==null){
			companies=new ConcurrentHashMap<String, CompanyVO>();
		}
		return companies;
	}

	public void setCompanies(ConcurrentMap<String, CompanyVO> companies) {
		this.companies = companies;
	}

}
